﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.IO;
using Newtonsoft.Json;
using System.Collections;
using System.Reflection;
using TCWireless.Component.Utility;
using TCWireless.Component.Utility.Security;
namespace Common
{
    public class RequestCommon
    {
        public static string WebServiceResponse(string OTA_UrlName, string requestXML, bool IsUseProxy = false)
        {
            try
            {
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(OTA_UrlName);
                request.Method = "GET";
                request.ContentType = "text/json; charset=utf-8";

                if (IsUseProxy)
                {
                    WebProxy proxy = new WebProxy();
                    proxy.Address = new Uri("http://coreproxysite.ctripcorp.com:8080");
                    request.UseDefaultCredentials = true;
                    request.Proxy = proxy;
                }
                byte[] data = Encoding.UTF8.GetBytes(requestXML);
                request.ContentLength = data.Length;
                Stream writer = request.GetRequestStream();
                writer.Write(data, 0, data.Length);
                writer.Close();
                request.Timeout = 10000000;
                WebResponse response = request.GetResponse();
                StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                String retXml = sr.ReadToEnd();
                sr.Close();
                return retXml;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        //protected void btnSubmitV1_Click(object sender, EventArgs e)
        //{
        //    ltlLog.Text = string.Empty;
        //    string url = this.txtPostURL.Text.Trim();
        //    string inputStr = this.txtPostXML.Text.Trim();
        //    string strTemp = string.Empty;
        //    this.ltlResult.Text = "";
        //    if (Request.Url.AbsoluteUri == url)
        //    {
        //        txtResult.Text = "请求的地址不正确";
        //        return;
        //    }

        //    if (!string.IsNullOrEmpty(url) && url.StartsWith("http:", StringComparison.CurrentCultureIgnoreCase))
        //    {
        //        try
        //        {
        //            ReqData reqData = JsonConvert.DeserializeObject<ReqData>(inputStr);
        //            this.NomalizeRequest(reqData);
        //            string reqJson = JsonConvert.SerializeObject(reqData).Replace("\r", "").Replace("\n", "");
        //            string strResponse = PostDataToServer(url, reqJson, HttpWebRequestMethod.POST, "280504b8b638913d3a8d1cd5a60f7046");
        //            strTemp = strResponse;
        //            txtResult.Text = FormatJson(strResponse);
        //        }
        //        catch (Exception exception)
        //        {
        //            ltlLog.Text = HandleException(url, inputStr, strTemp, exception);

        //            this.ltlResult.Text = "执行请求出错";

        //        }
        //    }
        //    else
        //    {
        //        this.ltlResult.Text = "请确认接口地址，接口地址为空或输入有误。";
        //    }
        //}

        private static string HandleException(string url, string inputStr, string strTemp, Exception exception)
        {
            Hashtable htCustomData = new Hashtable();
            htCustomData.Add("URL", url);
            if (!string.IsNullOrEmpty(inputStr))
                htCustomData.Add("XML_INPUT", inputStr);
            if (!string.IsNullOrEmpty(strTemp))
                htCustomData.Add("STR_RESPONSE", strTemp);

            StringBuilder logContentBuilder = new StringBuilder();
            logContentBuilder.Append(System.Environment.NewLine); //添加换行符
            logContentBuilder.AppendFormat("================================================{0}", System.Environment.NewLine);
            logContentBuilder.AppendFormat("[MethodName]:\t{0}{1}", MethodInfo.GetCurrentMethod().Name,
                                           System.Environment.NewLine);
            logContentBuilder.AppendFormat("[Exception ]:\t{0}{1}", exception.GetType().FullName, System.Environment.NewLine);
            logContentBuilder.AppendFormat("[Message   ]:\t{0}{1}", exception.Message, System.Environment.NewLine);
            logContentBuilder.AppendFormat("------------------------------------------------{0}", System.Environment.NewLine);
            logContentBuilder.AppendFormat("[StackTrace]:{0}{1}{2}", System.Environment.NewLine, exception.StackTrace,
                                           System.Environment.NewLine);

            if (htCustomData != null
                && htCustomData.Count > 0)
            {
                logContentBuilder.AppendFormat("------------------------------------------------{0}", System.Environment.NewLine);
                foreach (DictionaryEntry de in htCustomData)
                {
                    logContentBuilder.AppendFormat("[{0}]:\t{1}{2}", de.Key.ToString(), de.Value.ToString(),
                                                   System.Environment.NewLine);
                }
            }

            if (exception.InnerException != null)
            {
                logContentBuilder.AppendFormat("------------------------------------------------{0}", System.Environment.NewLine);
                logContentBuilder.AppendFormat("[InnerException          ]:\t{0}{1}",
                                               exception.InnerException.GetType().FullName, System.Environment.NewLine);
                logContentBuilder.AppendFormat("[InnerExceptionMessage   ]:\t{0}{1}", exception.InnerException.Message,
                                               System.Environment.NewLine);
                logContentBuilder.AppendFormat("[InnerExceptionStackTrace]:{0}{1}{2}", System.Environment.NewLine,
                                               exception.InnerException.StackTrace, System.Environment.NewLine);
            }
            logContentBuilder.AppendFormat("================================================{0}", System.Environment.NewLine);

            return logContentBuilder.ToString();
        }

        //protected void btnSubmitV3_Click(object sender, EventArgs e)
        //{
        //    ltlLog.Text = string.Empty;
        //    string url = this.txtPostURL.Text.Trim();
        //    string inputStr = this.txtPostXML.Text.Trim();
        //    string strTemp = string.Empty;
        //    this.ltlResult.Text = "";
        //    if (Request.Url.AbsoluteUri == url)
        //    {
        //        txtResult.Text = "请求的地址不正确";
        //        return;
        //    }

        //    if (!string.IsNullOrEmpty(url) && url.StartsWith("http:", StringComparison.CurrentCultureIgnoreCase))
        //    {
        //        try
        //        {
        //            ReqData reqData = JsonConvert.DeserializeObject<ReqData>(inputStr);
        //            this.NomalizeRequest(reqData);
        //            string reqJson = JsonConvert.SerializeObject(reqData).Replace("\r", "").Replace("\n", "");
        //            string strResponse = PostDataToServer(url, reqJson, HttpWebRequestMethod.POST, "FAC66642-5646-4FA6-B38F-2932D9AFE781", "3");
        //            strTemp = strResponse;
        //            txtResult.Text = FormatJson(strResponse);
        //        }
        //        catch (Exception exception)
        //        {
        //            ltlLog.Text = HandleException(url, inputStr, strTemp, exception);

        //            this.ltlResult.Text = "执行请求出错";
        //        }
        //    }
        //    else
        //    {
        //        this.ltlResult.Text = "请确认接口地址，接口地址为空或输入有误。";
        //    }
        //}

        //protected void btnSubmitV4_Click(object sender, EventArgs e)
        //{
        //    ltlLog.Text = string.Empty;
        //    string url = this.txtPostURL.Text.Trim();
        //    string inputStr = this.txtPostXML.Text.Trim();
        //    string strTemp = string.Empty;
        //    this.ltlResult.Text = "";
        //    if (Request.Url.AbsoluteUri == url)
        //    {
        //        txtResult.Text = "请求的地址不正确";
        //        return;
        //    }

        //    if (!string.IsNullOrEmpty(url) && url.StartsWith("http:", StringComparison.CurrentCultureIgnoreCase))
        //    {
        //        try
        //        {
        //            ReqData reqData = JsonConvert.DeserializeObject<ReqData>(inputStr);
        //            this.NomalizeRequest(reqData);
        //            string reqJson = JsonConvert.SerializeObject(reqData).Replace("\r", "").Replace("\n", "");
        //            string strResponse = PostDataToServer(url, reqJson, HttpWebRequestMethod.POST, "4957CA66-37C3-46CB-B26D-E3D9DCB51535", "4");
        //            strTemp = strResponse;
        //            txtResult.Text = FormatJson(strResponse);
        //        }
        //        catch (Exception exception)
        //        {
        //            ltlLog.Text = HandleException(url, inputStr, strTemp, exception);

        //            this.ltlResult.Text = "执行请求出错";
        //        }
        //    }
        //    else
        //    {
        //        this.ltlResult.Text = "请确认接口地址，接口地址为空或输入有误。";
        //    }
        //}

        //protected void btnSubmitV99_Click(object sender, EventArgs e)
        //{
        //    ltlLog.Text = string.Empty;
        //    string url = this.txtPostURL.Text.Trim();
        //    string inputStr = this.txtPostXML.Text.Trim();
        //    string strTemp = string.Empty;
        //    this.ltlResult.Text = "";
        //    if (Request.Url.AbsoluteUri == url)
        //    {
        //        txtResult.Text = "请求的地址不正确";
        //        return;
        //    }

        //    if (!string.IsNullOrEmpty(url) && url.StartsWith("http:", StringComparison.CurrentCultureIgnoreCase))
        //    {
        //        try
        //        {
        //            ReqData reqData = JsonConvert.DeserializeObject<ReqData>(inputStr);
        //            this.NomalizeRequest(reqData);
        //            string reqJson = JsonConvert.SerializeObject(reqData).Replace("\r", "").Replace("\n", "");
        //            string strResponse = PostDataToServer(url, reqJson, HttpWebRequestMethod.POST, "d2b2aa55-281e-4e7c-91b7-85ba3a7212fc", "99");
        //            strTemp = strResponse;
        //            txtResult.Text = FormatJson(strResponse);
        //        }
        //        catch (Exception exception)
        //        {
        //            ltlLog.Text = HandleException(url, inputStr, strTemp, exception);

        //            this.ltlResult.Text = "执行请求出错";
        //        }
        //    }
        //    else
        //    {
        //        this.ltlResult.Text = "请确认接口地址，接口地址为空或输入有误。";
        //    }
        //}

        public static void NomalizeRequest(ReqData reqData)
        {
            if (reqData == null || reqData.request == null && reqData.request.header == null) return;

            if (string.IsNullOrWhiteSpace(reqData.request.header.version))
            {
                reqData.request.header.version = "20111128102912";
            }

            if (string.IsNullOrWhiteSpace(reqData.request.header.accountID))
            {
                reqData.request.header.accountID = "C26B007F-C89E-431A-B8CC-493BECBDD8A2";
            }

            if (string.IsNullOrWhiteSpace(reqData.request.header.serviceName))
            {
                return;
            }

            if (string.IsNullOrWhiteSpace(reqData.request.header.reqTime))
            {
                reqData.request.header.reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
            }

            if (string.IsNullOrWhiteSpace(reqData.request.header.digitalSign))
            {
                string accountKey = string.Empty;
                switch (reqData.request.header.accountID.ToUpper())
                {
                    case "102B0C82-0778-4DBB-8266-1241E8C6AF9A":
                        accountKey = "4f1afa2ff95c4a7e";
                        break;
                    case "B95A2284-332E-4FB0-BD47-7E6A828D7E58":
                        accountKey = "2b2a5d4d0e155fa3";
                        break;
                    case "7187C05F-951B-4CA6-888A-B8EDF8C6679F":
                        accountKey = "fb13a093870f2028";
                        break;
                    case "67C77F6C-54D0-4A06-A4EB-E594ADA76B00":
                        accountKey = "0f9c205a0c4f28c4";
                        break;
                    case "3F004C6D-58B7-4616-98F1-A0BE51048144":
                        accountKey = "3d5d6d102c19c371";
                        break;
                    case "BE7688CE-6A62-4559-AB6F-35C9BB67A1F6":
                        accountKey = "295525f25e0ecda1";
                        break;
                    case "C26B007F-C89E-431A-B8CC-493BECBDD8A2":
                        accountKey = "8874d8a8b8b391fbbd1a25bda6ecda11";
                        break;
                    case "5EE7B429-B8C6-400F-8B87-3C384C4EA68A":
                        accountKey = "c40af6c78c5c5413d8c435af5166ba6e";
                        break;
                    case "E10E97C7-455B-4614-9C92-FFE5691D2CF0":
                        accountKey = "6fe0f3e1b319f63f9005452e362858e3";
                        break;
                    case "C7F5CE31-F5D8-4BF9-B305-1D9FE3963A4A":
                        accountKey = "48b9f70a6e1bc7cb";
                        break;
                    case "5EE7B429-B8C6-400F-8B87-3C384C4EA68B":
                        accountKey = "c40af6c78c5c5413d8c435af5166ba6b";
                        break;
                    case "F104D24B-47A4-4821-BB7C-000093EF21E8":
                        accountKey = "c40af6c78c5c5413d8c435af5166ba7z";
                        break;
                    case "84D8867A-89B6-423D-B64F-3C2923DA5923":
                        accountKey = "03bf6b4b6098334421afbe0cb62a22c9";
                        break;
                }

                List<string> stringList = new List<string>();
                stringList.Add(string.Format("Version={0}", reqData.request.header.version));
                stringList.Add(string.Format("AccountID={0}", reqData.request.header.accountID));
                stringList.Add(string.Format("ServiceName={0}", reqData.request.header.serviceName));
                stringList.Add(string.Format("ReqTime={0}", reqData.request.header.reqTime));

                string[] originalstr = stringList.ToArray();
                string[] sortedstr = BubbleSort(originalstr);
                reqData.request.header.digitalSign = Encryption.GetMD5ByArray(sortedstr, accountKey, "utf-8");
            }
        }

        //protected void btnReset_Click(object sender, EventArgs e)
        //{
        //    this.txtPostURL.Text = string.Empty;
        //    this.txtPostXML.Text = string.Empty;
        //    this.ltlResult.Text = string.Empty;
        //    this.txtResult.Text = string.Empty;
        //}

        //protected void Button1_Click(object sender, EventArgs e)
        //{
        //    this.txtResult.Text = string.Empty;
        //}

        //protected void btnJsonFormat_Click(object sender, EventArgs e)
        //{

        //    if (!string.IsNullOrWhiteSpace(txtPostXML.Text.Trim()) && txtPostXML.Text.Trim().Length > 100)
        //    {
        //        txtPostXML.Text = FormatJson(txtPostXML.Text.Trim());
        //    }
        //}

        //protected void btnMemberIdDecode_Click(object sender, EventArgs e)
        //{
        //    try
        //    {
        //        txtResult.Text = DecryptMemberId(txtPostXML.Text);
        //    }
        //    catch (Exception ex)
        //    {
        //        ltlResult.Text = ex.Message + ex.StackTrace;
        //    }

        //}

        public static string DecryptMemberId(string base64MemberId)
        {
            string memberId = string.Empty;

            if (base64MemberId.StartsWith("A0_"))
            {
                base64MemberId = base64MemberId.Replace("A0_", string.Empty);
                memberId = DecryptMemberId(base64MemberId, "a!Q@#z$Eddtc&&*!jhd(HjitEfhyF^%b");
            }
            else if (base64MemberId.StartsWith("I0_"))
            {
                base64MemberId = base64MemberId.Replace("I0_", string.Empty);
                memberId = DecryptMemberId(base64MemberId, "i!Q@#z$Eddtc&&*!jhd(HjitEfhyF^%b");
            }
            else
            {
                memberId = SecurityHelper.AESDencryByHex(base64MemberId, "q!Q@#z$Eddtc&&*!jhd(HjitEfhy)^%r");
            }
            return memberId;
        }

        private static string DecryptMemberId(string base64MemberId, string key)
        {
            if (string.IsNullOrWhiteSpace(base64MemberId))
                return string.Empty;

            string strResult = string.Empty;
            try
            {
                byte[] data = new byte[(base64MemberId.Length) / 2];
                for (int i = 0; i < data.Length; i++)
                {
                    data[i] = (byte)(
                       "0123456789abcdef".IndexOf(base64MemberId[i * 2]) * 16 +
                       "0123456789abcdef".IndexOf(base64MemberId[i * 2 + 1])
                    );
                }

                byte[] keyBytes = Encoding.UTF8.GetBytes(key);
                byte[] iv = new byte[] { 0x13, 0x33, 0x5D, 0x7F, 0x52, 0x29, 0x2C, 0x15, 0x3B, 0x51, 0x55, 0x23, 0x4F, 0x19, 0x36, 0x3D };

                strResult = AESHelper.AESDecrypt(data, keyBytes, iv);
            }
            catch
            {
                return string.Empty;
            }
            return strResult;
        }
        /// <summary>
        /// Json 格式化
        /// </summary>
        /// <param name="strJson"></param>
        /// <returns></returns>
        private static string FormatJson(string strJson)
        {
            StringBuilder strNew = new StringBuilder();
            string strNewLine = "\r\n";
            char strSpance = '\t';
            int tabNum = 0;
            for (int i = 0; i < strJson.Length; i++)
            {
                if (strJson[i] == '{')
                {
                    strNew.Append(strNewLine);
                    strNew.Append(strSpance, tabNum);
                    strNew.Append(strJson[i]);
                    tabNum++;
                    strNew.Append(strNewLine);
                    strNew.Append(strSpance, tabNum);
                }
                else if (strJson[i] == '}')
                {
                    tabNum--;
                    strNew.Append(strNewLine);
                    strNew.Append(strSpance, tabNum);
                    strNew.Append(strJson[i]);
                }
                else if (strJson[i] == ',')
                {
                    strNew.Append(strJson[i]);
                    strNew.Append(strNewLine);
                    strNew.Append(strSpance, tabNum);
                }
                else
                {
                    strNew.Append(strJson[i]);
                }
            }
            return strNew.ToString().TrimStart('\r').TrimStart('\n');
        }

        /// <summary>
        /// 数组排序（冒泡排序法）
        /// </summary>
        /// <param name="r"></param>
        /// <returns></returns>
        private static string[] BubbleSort(string[] r)
        {
            int i, j; //交换标志 
            string temp;
            bool exchange;

            for (i = 0; i < r.Length; i++) //最多做R.Length-1趟排序 
            {
                exchange = false; //本趟排序开始前，交换标志应为假

                for (j = r.Length - 2; j >= i; j--)
                {
                    if (String.CompareOrdinal(r[j + 1], r[j]) < 0)　//交换条件
                    {
                        temp = r[j + 1];
                        r[j + 1] = r[j];
                        r[j] = temp;

                        exchange = true; //发生了交换，故将交换标志置为真 
                    }
                }

                if (!exchange) //本趟排序未发生交换，提前终止算法 
                {
                    break;
                }
            }
            return r;
        }
        public static string PostDataToServer(string url, string data, HttpWebRequestMethod method, string reqDataKey, string secVer = "")
        {
            return PostDataToServer(url,data,method,reqDataKey,false,secVer);
        }
        /// <summary>
        /// 向服务器提交XML数据
        /// </summary>
        /// <param name="url">远程访问的地址</param>
        /// <param name="data">参数</param>
        /// <param name="method">Http页面请求方法</param>
        /// <returns>远程页面调用结果</returns>
        public static string PostDataToServer(string url, string data, HttpWebRequestMethod method, string reqDataKey, bool isUseProxy, string secVer = "")
        {
            HttpWebRequest request = null;
            try
            {
                request = WebRequest.Create(url) as HttpWebRequest;
                request.Timeout = 60000;

                if (isUseProxy)
                {
                    WebProxy proxy = new WebProxy();
                    proxy.Address = new Uri("http://61.155.197.173:8018");
                    request.UseDefaultCredentials = true;
                    request.Proxy = proxy;
                }


                switch (method)
                {
                    case HttpWebRequestMethod.GET:
                        request.Method = HttpWebRequestMethod.GET.ToString();
                        break;
                    case HttpWebRequestMethod.POST:
                        {
                            request.Method = HttpWebRequestMethod.POST.ToString();

                            byte[] bdata = Encoding.UTF8.GetBytes(data);
                            request.ContentType = "application/xml;charset=utf-8";
                            request.ContentLength = bdata.Length;
                            request.Headers.Add("reqdata", Encryption.GetMD5(string.Format("{0}{1}", data, reqDataKey)));

                            if (!secVer.IsNullOrWhiteSpace())
                            {
                                request.Headers.Add("sec-ver", secVer);
                            }

                            Stream streamOut = request.GetRequestStream();
                            streamOut.Write(bdata, 0, bdata.Length);
                            streamOut.Close();
                        }
                        break;
                }



                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Stream streamIn = response.GetResponseStream();

                StreamReader reader = new StreamReader(streamIn);
                string result = reader.ReadToEnd();
                reader.Close();
                streamIn.Close();
                response.Close();

                return result;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return "";
            }
        }

    }

    public class ReqData
    {
        public Request request { get; set; }
    }

    public class Request
    {
        public Head header { get; set; }
        public dynamic body { get; set; }
    }

    public class Head
    {
        public string version { get; set; }
        public string accountID { get; set; }
        public string serviceName { get; set; }
        public string digitalSign { get; set; }
        public string reqTime { get; set; }
    }

    public sealed class RequestEntity
    {
        public RequestData request { get; set; }
    }

    public class RequestData
    {

        public RequestHeader header { get; set; }
        public dynamic body { get; set; }

    }

    public class RequestHeader
    {
        public string version { get; set; }
        public string accountID { get; set; }
        public string serviceName { get; set; }
        public string digitalSign { get; set; }
        public string reqTime { get; set; }
        public string encryptEffort { get; set; }
    }

    public sealed class ResponseEntity
    {
        public ResponseData response { get; set; }
    }

    public class ResponseData
    {
        public ResponseHeader header { get; set; }

        public dynamic body { get; set; }

        /// <summary>
        /// 获取响应输出JSON字符串
        /// </summary>
        /// <param name="response"></param>
        /// <returns></returns>
        public string ToJson()
        {
            string strJson = "";
            if (body != null)
            {
                var jSetting = new JsonSerializerSettings();
                jSetting.NullValueHandling = NullValueHandling.Ignore;
                jSetting.Formatting = Formatting.Indented;
                //jSetting.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
                strJson = JsonConvert.SerializeObject(this, Formatting.None, jSetting);
            }
            else
            {
                strJson = JsonConvert.SerializeObject(this.header);
                strJson = "{\"header\":" + strJson + "}";
            }
            return strJson;
        }
    }

    public class ResponseHeader
    {
        private string m_RspType = "";
        private string m_RspCode = "";
        private string m_RspDesc = "";

        public string rspType
        {
            get
            {
                if (string.IsNullOrWhiteSpace(m_RspType))
                    m_RspType = "";
                return m_RspType;
            }
            set { m_RspType = value; }
        }

        public string rspCode
        {
            get
            {
                if (string.IsNullOrWhiteSpace(m_RspCode))
                    m_RspCode = "";
                return m_RspCode;
            }
            set { m_RspCode = value; }
        }

        public string rspDesc
        {
            get
            {
                if (string.IsNullOrWhiteSpace(m_RspDesc))
                    m_RspDesc = "";
                return m_RspDesc;
            }
            set { m_RspDesc = value; }
        }
    }

    public class RequestModel
    {
        public RequestData request { get; set; }
    }


    public class ResponseModel
    {
        public ResponseData response { get; set; }
    }
}
